package cn.com.kh;

import cn.com.callback.apiGetToken;
import cn.com.kh.KHUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.Map;

public class HttpsUtil {
    private static final Log log = LogFactory.getLog(HttpsUtil.class);

    private static String HttpsKeyFile = "/data/apache-tomcat-9.0.34/webapps/ngsapitask/client.p12";
    private static String HttpsKeyPassword = "Letmein#YNGD@2022";

    public static String doHttpPostUseHead(String url, String body, String charset, int timeout, Map headMap, String KeyFile, String KeyPassword) throws Exception {
        String content = "";
        CloseableHttpClient httpClient = null;
        log.debug("HttpPost调用信息-url:" + url + " body:" + body + " charset:" + charset + " timeout:" + timeout + " headMap:" + headMap.toString() + " KeyFile:" + KeyFile + " KeyPassword:" + KeyPassword);
        try {
            HttpPost httppost = new HttpPost(url);

            HttpsKeyFile = KHUtil.isNull(KeyFile) ? HttpsKeyFile : KeyFile;
            HttpsKeyPassword = KHUtil.isNull(KeyPassword) ? HttpsKeyPassword : KeyPassword;
            log.debug("HttpPost调用信息加密信息-HttpsKeyFile:" + HttpsKeyFile + " HttpsKeyPassword:" + HttpsKeyPassword);

            // 处理头文件信息
            if (headMap != null) {
                Iterator entries = headMap.entrySet().iterator();

                while (entries.hasNext()) {
                    Map.Entry entry = (Map.Entry) entries.next();
                    String key = (String) entry.getKey();
                    log.debug("key:" + key);
                    String value = (String) entry.getValue();
                    log.debug("value:" + value);
                    httppost.addHeader(key, value);
                }
            }

            // 设置超时信息
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout).setConnectionRequestTimeout(timeout).setSocketTimeout(timeout).build();
            httppost.setConfig(requestConfig);

            StringEntity se = new StringEntity(body, charset);
            httppost.setEntity(se);

            httpClient = getHttpClient();
            CloseableHttpResponse httpResponse = httpClient.execute(httppost);

            try {
                HttpEntity httpEntity = httpResponse.getEntity();
                if (httpEntity != null) {
                    content = EntityUtils.toString(httpEntity, charset);
                }
            } finally {
                httpResponse.close();
            }
            log.debug("调用API完成结果:" + content);


        } catch (Exception e) {
            log.error("调用API失败-发生异常", e);
        } finally {
            httpClient.close();
        }
        return content;
    }

    public static String doHttpGetUseHead(String url, String charset, int timeout, Map headMap, String KeyFile, String KeyPassword) throws Exception {
        String content = "";
        CloseableHttpClient httpClient = null;
        log.debug("HttpPost调用信息-url:" + url + " charset:" + charset + " timeout:" + timeout + " headMap:" + headMap.toString() + " KeyFile:" + KeyFile + " KeyPassword:" + KeyPassword);

        try {
            HttpGet httpgets = new HttpGet(url);

            HttpsKeyFile = KHUtil.isNull(KeyFile) ? HttpsKeyFile : KeyFile;
            HttpsKeyPassword = KHUtil.isNull(KeyPassword) ? HttpsKeyPassword : KeyPassword;
            log.debug("HttpPost调用信息加密信息-HttpsKeyFile:" + HttpsKeyFile + " HttpsKeyPassword:" + HttpsKeyPassword);

            // 处理头文件信息
            if (headMap != null) {
                Iterator entries = headMap.entrySet().iterator();

                while (entries.hasNext()) {
                    Map.Entry entry = (Map.Entry) entries.next();
                    String key = (String) entry.getKey();
                    log.debug("key:" + key);
                    String value = (String) entry.getValue();
                    log.debug("value:" + value);
                    httpgets.addHeader(key, value);
                }
            }

            // 设置超时信息
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout).setConnectionRequestTimeout(timeout).setSocketTimeout(timeout).build();
            httpgets.setConfig(requestConfig);

            httpClient = getHttpClient();

            CloseableHttpResponse httpResponse = httpClient.execute(httpgets);
            try {
                HttpEntity httpEntity = httpResponse.getEntity();
                if (httpEntity != null) {
                    content = EntityUtils.toString(httpEntity, charset);
                }
            } finally {
                httpResponse.close();
            }
            log.debug("调用API完成结果:" + content);

        } catch (Exception e) {
            log.error("调用API失败-发生异常", e);
        } finally {
            httpClient.close();
        }

        return content;
    }

    public static CloseableHttpClient getHttpClient() throws Exception {
        CloseableHttpClient httpclient = null;
        try {

            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            keyStore.load(new FileInputStream(new File(HttpsKeyFile)), HttpsKeyPassword.toCharArray());
            SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).loadKeyMaterial(keyStore, HttpsKeyPassword.toCharArray()).build();
            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, new HostnameVerifier() {
                @Override
                public boolean verify(String s, SSLSession sslSession) {
                    return true;
                }
            });
            httpclient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
        } catch (FileNotFoundException e) {
            log.error("调用API失败-系统找不到指定的文件", e);
            throw new Exception("由于系统找不到指定的文件-获取HttpClient异常");
        } catch (Exception e) {
            log.error("调用API失败-发生异常", e);
            throw new Exception("由于由于未知原因导致获取HttpClient异常:" + e.getMessage());
        }

        return httpclient;
    }
}
